package com.shipwe.loans.http

import com.shipwe.http.OkHttp
import com.shipwe.http.cache.CacheEntity
import com.shipwe.http.cache.CacheMode
import com.shipwe.http.callback.StringCallback
import com.shipwe.http.cookie.CookieJarImpl
import com.shipwe.http.cookie.store.DBCookieStore
import com.shipwe.http.interceptor.HttpLoggingInterceptor
import com.shipwe.http.model.HttpHeaders
import com.shipwe.http.model.Response
import com.shipwe.loans.MyApps
import com.shipwe.loans.configs.ShipweConfigs
import com.shipwe.loans.http.ApiService.addCommonParams
import com.shipwe.loans.utils.ShipweAppAesUtil
import com.shipwe.loans.utils.log.JsonFormat
import com.shipwe.loans.utils.log.ShipweLogger
import okhttp3.OkHttpClient
import org.json.JSONObject
import java.io.File
import java.util.concurrent.TimeUnit
import java.util.logging.Level

/**
 * Shipwe
 * @Author wwdeng
 * @CreateTime: 2024/11/20 17:38
 * @Annotation：网络请求
 */
class HttpLoader: IHttpLoader {

    init {
        OkHttp.getInstance().init(MyApps.app)
        val builder = OkHttpClient.Builder()
        //log相关
        val loggingInterceptor = HttpLoggingInterceptor(ShipweConfigs.SHIPWE_APPNAME)
        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY) //log打印级别，决定了log显示的详细程度
        loggingInterceptor.setColorLevel(Level.INFO) //log颜色级别，决定了log在控制台显示的颜色
        builder.addInterceptor(loggingInterceptor) //添加OkGo默认debug日志
        //第三方的开源库，使用通知显示当前请求的log，不过在做文件下载的时候，这个库好像有问题，对文件判断不准确

        //超时时间设置，默认60秒
        builder.readTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的读取超时时间
        builder.writeTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的写入超时时间
        builder.connectTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的连接超时时间
        //自动管理cookie（或者叫session的保持），以下几种任选其一就行
        //builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie，如果cookie不过期，则一直有效
        builder.cookieJar(CookieJarImpl(DBCookieStore(MyApps.context))) //使用数据库保持cookie，如果cookie不过期，则一直有效

        // 其他统一的配置
        // 详细说明看GitHub文档：https://github.com/jeasonlzy/
        OkHttp.getInstance().init(MyApps.app) //必须调用初始化
            .setOkHttpClient(builder.build()) //建议设置OkHttpClient，不设置会使用默认的
            .setCacheMode(CacheMode.NO_CACHE) //全局统一缓存模式，默认不使用缓存，可以不传
            .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE) //全局统一缓存时间，默认永不过期，可以不传
            .setRetryCount(3) //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0

        //添加通用请求头
        val httpHeaders = HttpHeaders()
        httpHeaders.put("appid", ShipweConfigs.SHIPWE_APPNAME)
        httpHeaders.put("product", ShipweConfigs.SHIPWE_APPNAME)
        OkHttp.getInstance().addCommonHeaders(httpHeaders)
    }

    /**
     * post 请求
     */
    override fun post(url: String, params: JSONObject, tag: Any, callback: IHttpCallback) {
        val aesParams = ShipweAppAesUtil.encryptDefault(params.toString())
        ShipweLogger.e("HttpUrl：  $url")
        ShipweLogger.e("HttpParams： $params")
        ShipweLogger.e("HttpParams AES：  $aesParams")

        OkHttp.post<String>(url) // 请求方式和请求url
            .tag(tag) // 请求的 tag, 主要用于取消对应的请求
            .upString(aesParams)
            .execute(object : StringCallback() {
                override fun onSuccess(response: Response<String>) {
                    val body = response.body()
                    if (response.code() != 200 || body == null || body.isEmpty()){
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",response.code())
                        errorObj.put("errorMsg",response.message())
                        callback.onRequestError(errorObj)
                        return
                    }

                    val result = ShipweAppAesUtil.decryptDefault(body)
                    if (result.isNotEmpty()){
                        Thread { ShipweLogger.i(JsonFormat.format(result)) }.start()
                        val data = JSONObject(result)
                        callback.onRequestSuccess(data)
                    } else {
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",-1)
                        errorObj.put("errorMsg","http request error $result")
                        callback.onRequestError(errorObj)
                    }
                }

                override fun onError(response: Response<String>) {
                    val errorObj = JSONObject()
                    errorObj.put("errorCode",response.code())
                    errorObj.put("errorMsg",response.message())
                    callback.onRequestError(errorObj)
                }
                override fun onFinish() {
                    callback.onRequestFinish()
                }
            })
    }

    /**
     * 文件上传
     */
    override fun upload(filePath: String, tag: Any, callback: StringCallback) {
        if (filePath.isEmpty()){
            return
        }
        val httpUrl = ApiService.getHttpUrl(true)
        OkHttp.post<String>(httpUrl) // 请求方式和请求url
            .tag(tag) // 请求的 tag, 主要用于取消对应的请求
            .params("image",File(filePath))   //这种方式为一个key，对应一个文件
            .isMultipart(true)
            .execute(callback)
    }

    /**
     * 添加打点事件
     */
    override fun addPoint(eventName: String, remark: String, tag: Any, callback: IHttpCallback) {
        ShipweLogger.e(">>>>>>>>>>>>>>eventName：$eventName，remark：$remark")

        val eventType = eventName.uppercase()//转大写
        val httpUrl = ApiService.getHttpUrl()
        val params = JSONObject().addCommonParams().apply {
            put("path", ApiService.API_PATH.SHIPWE_API_TRACK_EVENT_PATH)
            put("type",eventType)//事件类型
            put("remark",remark)//事件备注
        }

        val aesParams = ShipweAppAesUtil.encryptDefault(params.toString())
        ShipweLogger.e("event url：  $httpUrl")
        ShipweLogger.e("event params： $params")
        ShipweLogger.e("event params AES：  $aesParams")
        OkHttp.post<String>(httpUrl) // 请求方式和请求url
            .tag(tag) // 请求的 tag, 主要用于取消对应的请求
            .upString(aesParams)
            .execute(object : StringCallback() {
                override fun onSuccess(response: Response<String>) {
                    val result = ShipweAppAesUtil.decryptDefault(response.body())
                    Thread { ShipweLogger.i("event Response：${JsonFormat.format(result)}") }.start()
                }
                override fun onError(response: Response<String>) {
                }
                override fun onFinish() {
                }
            })
    }

    /**
     * 取消请求
     */
    override fun cancelTag(tag: Any) {
        OkHttp.getInstance().cancelTag(tag)
    }

}